﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management.Automation;
using System.Collections;
using System.Security;
using agsXMPP;
using System.Management.Automation.Host;
using agsXMPP.protocol.client;

namespace PoshXmpp
{
    [Cmdlet(VerbsLifecycle.Start, "Chat")]
    public class StartChatCommand : XmppCommandBase
    {

        #region Parameters
        [Parameter(Position = 0,
            Mandatory = true,
            HelpMessage = "Jabber Id to start chat to")]
        [Alias("JabberId")]
        [ValidateNotNullOrEmpty]
        public string ChatId { get; set; }

        [Parameter(Position = 1,
            Mandatory = true,
            HelpMessage = "Nickname to use")]
        [ValidateNotNullOrEmpty]
        public string Nickname { get; set; }
        #endregion

        Jid Chat = null;

        protected override void ProcessRecord()
        {
            Chat = new Jid(ChatId);
            Client.JoinChat(Chat, Nickname);
            bool stay = true;

            WriteObject("Joining " + Chat.User + " ... type /quit to exit");
            WriteObject("/list to see users, /help for more commands");
            DateTime last = DateTime.Now;
            while (!PrintMessages()) { }
            while (stay)
            {
                PrintMessages();

                // TODO: figure out how to tell if there's a LINE available...
                if(Host.UI.RawUI.KeyAvailable)
                {
                    WriteObject("Press ENTER to send the command and continue reading");
                    stay = ProcessLine(Host.UI.ReadLine());
                }
                //// resend presence every minute or so...
                //if (DateTime.Now - last > TimeSpan.FromMinutes(1))
                //{
                //    Client.JoinChat(Chat, Nickname);
                //}
                System.Threading.Thread.Sleep(100);
            }
            Client.LeaveChat(Chat);
        }

        private bool PrintMessages( )
        {
            bool messages = false;
            foreach (Message m in Client.Messages)
            {
                Jid bare = new Jid(m.From.Bare);
                if (Client.ChatManager.IsInRoom(bare))
                {
                    if (String.IsNullOrEmpty(m.From.Resource))
                    {
                        WriteObject(string.Format("{0} :: {1}", m.From.User, m.Body, DateTime.Now, m.From.User));
                    }
                    else
                    {
                        WriteObject(string.Format("{2:hh:mm:ss t} [{3}]<{0}> {1}", m.From.Resource, m.Body, DateTime.Now, m.From.User));
                    }
                }
                else
                {
                    WriteObject(string.Format("{2:hh:mm:ss t} <{0}> {1}", bare, m.Body, DateTime.Now));
                }
                messages = true;
            }
            return messages;
        }

        private bool ProcessLine(string line)
        {
            bool stay = true;
            try
            {
                string[] cmds = line.Split(' ');
                switch (cmds[0])
                {
                    case "/quit":
                        Client.LeaveChat(Chat);
                        stay = false;
                        break;
                    case "/priv":
                        try
                        {
                            Jid to = new Jid(cmds[1]);
                            int start = cmds[0].Length + cmds[1].Length + 2;
                            if (start < line.Length)
                            {
                                Client.SendMsg(to, line.Substring(start));
                            }
                            else
                            {
                                WriteWarning("Nothing to send...");
                            }
                        }
                        catch
                        {
                            WriteWarning("Malformed privmsg. You have to specify a jabber id follwed by the message to send");
                        }
                        break;
                    case "/list":
                        foreach (string nick in Client.ChatManager.GetUsers(Chat))
                        {
                            WriteObject(nick);
                        }
                        break;
                    case "/nick":
                        if (cmds.Length > 1)
                        {
                            Nickname = cmds[1];
                            Client.JoinChat(Chat, Nickname);
                        }
                        else goto case "/help";
                        break;
                    case "/help":
                        WriteObject("/quit - stop chat");
                        WriteObject("/priv <user>@<host> <message> - send a message to a jabberid");
                        WriteObject("/list - list users");
                        WriteObject("/nick <nickname> - change nickname");


                        WriteObject("/help - this list");
                        break;
                    default:
                        if (line.Length > 0) Client.SendMsg(Chat, line);
                        break;
                }
            }
            catch (Exception ex)
            {
                WriteError(new ErrorRecord(ex, "Couldn't process chat", ErrorCategory.OperationStopped, Client));
                stay = false;
            }
            return stay;
        }
    }
}
